#include <sxPlotController.h>
#include <sxCanvas.h>

Sx::Interface::PlotController::PlotController(Viewport* viewport, const std::shared_ptr<Canvas>& canvas, const std::shared_ptr<ScenePickingController>& pickingController, const std::shared_ptr<RendererImplementation>& cameraRenderer, const std::shared_ptr<RendererImplementation>& plotRenderer) : 
	SceneController(viewport, canvas, pickingController, cameraRenderer) {

	this->plot = std::make_shared<PlotAxes_Archetype>(plotRenderer, 0, 20, 10, 10, 0, 0, 1.0f);

	this->plot->getObject()->setDisplayGrid(Math::YZ, false);
	this->plot->getObject()->setDisplayGrid(Math::XZ, false);
	this->plot->getObject()->hideZAxis();
	this->camera->getObject()->setProjection(Math::ORTHOGRAPHIC);
	this->camera->getObject()->setView(Math::FRONT);
}

Sx::Interface::PlotController::PlotController(Viewport* viewport, const std::shared_ptr<Canvas>& canvas, const std::shared_ptr<ScenePickingController>& pickingController, const std::shared_ptr<RendererImplementation>& cameraRenderer, const std::shared_ptr<RendererImplementation>& plotRenderer, unsigned int nxTicks,  unsigned int pxTicks, unsigned int nyTicks, unsigned int pyTicks, unsigned int nzTicks, unsigned int pzTicks, float spacing) :
	SceneController(viewport, canvas, pickingController, cameraRenderer) {
	
	this->plot = std::make_shared<PlotAxes_Archetype>(plotRenderer, nxTicks, pxTicks, nyTicks, pyTicks, nzTicks, pzTicks, spacing);

	this->plot->getObject()->setDisplayGrid(Math::YZ, false);
	this->plot->getObject()->setDisplayGrid(Math::XZ, false);
	this->plot->getObject()->hideZAxis();
	this->camera->getObject()->setProjection(Math::ORTHOGRAPHIC);
	this->camera->getObject()->setView(Math::FRONT);
}

Sx::Interface::PlotController::~PlotController() {}

bool Sx::Interface::PlotController::initialize() {
	SceneController::initialize();
	return this->plot->construct();
}

void Sx::Interface::PlotController::render() const {
	SceneController::preRender();
		this->plot->render();
	SceneController::postRender();
}

bool Sx::Interface::PlotController::setDisplayX(bool b) {
	if ( nullptr == this->plot ) return false;
	return this->plot->setDisplayX(b);
}

bool Sx::Interface::PlotController::setDisplayY(bool b) {
	if ( nullptr == this->plot ) return false;
	return this->plot->setDisplayY(b);
}

bool Sx::Interface::PlotController::setDisplayZ(bool b) {
	if ( nullptr == this->plot ) return false;
	return this->plot->setDisplayZ(b);
}

bool Sx::Interface::PlotController::setDisplayTicks(bool b) {
	if ( nullptr == this->plot ) return false;
	return this->plot->setDisplayTicks(b);
}

bool Sx::Interface::PlotController::setDisplayTickLabels(bool b) {
	if ( nullptr == this->plot ) return false;
	return this->plot->setDisplayTickLabels(b);
}

bool Sx::Interface::PlotController::setDisplayGrid(bool b) {
	if ( nullptr == this->plot ) return false;
	return this->plot->setDisplayGrid(b);
}

bool Sx::Interface::PlotController::setDisplayGrid(Math::AxisPlane plane, bool b) {
	if ( nullptr == this->plot ) return false;
	return this->plot->setDisplayGrid(plane, b);
}

bool Sx::Interface::PlotController::setXTicks(unsigned int ticks, bool positive) {
	if ( nullptr == this->plot ) {
		std::cerr << "[PlotController:setXTicks] Error: Plot archetype not initialized (nullptr)." << std::endl;
		return false;
	}

	return this->plot->setXTicks(ticks, positive);
}

bool Sx::Interface::PlotController::setYTicks(unsigned int ticks, bool positive) {
	if ( nullptr == this->plot ) {
		std::cerr << "[PlotController:setYTicks] Error: Plot archetype not initialized (nullptr)." << std::endl;
		return false;
	}

	return this->plot->setYTicks(ticks, positive);
}

bool Sx::Interface::PlotController::setZTicks(unsigned int ticks, bool positive) {
	if ( nullptr == this->plot ) {
		std::cerr << "[PlotController:setZTicks] Error: Plot archetype not initialized (nullptr)." << std::endl;
		return false;
	}

	return this->plot->setZTicks(ticks, positive);
}

bool Sx::Interface::PlotController::setGridTicks(unsigned int nxTicks, unsigned int pxTicks, unsigned int nyTicks, unsigned int pyTicks, unsigned int nzTicks, unsigned int pzTicks) {
	if ( nullptr == this->plot ) {
		std::cerr << "[PlotController:setGridTicks] Error: Plot archetype not initialized (nullptr)." << std::endl;
		return false;
	}

	return this->plot->setGridTicks(nxTicks, pxTicks, nyTicks, pyTicks, nzTicks, pzTicks);
}

bool Sx::Interface::PlotController::setLabelInterval(unsigned int interval) {
	if ( this->plot == nullptr ) return false;
	if ( this->plot->getObject() == nullptr ) return false;

	this->plot->getObject()->setTickLabelInterval(interval);
	return true;
}

void Sx::Interface::PlotController::mousePressEvent(int x, int y, MouseButton button, ModifierKey modifierKey) {
	ViewController::mousePressEvent(x, y, button, modifierKey);
}

void Sx::Interface::PlotController::mouseReleaseEvent(int x, int y, MouseButton button, ModifierKey modifierKey) {
	ViewController::mouseReleaseEvent(x, y, button, modifierKey);
}

void Sx::Interface::PlotController::mouseClickEvent(int x, int y, MouseButton button, ModifierKey modifierKey) {
	ViewController::mouseClickEvent(x, y, button, modifierKey);
}

void Sx::Interface::PlotController::mouseMoveEvent(int x, int y, MouseButton button, ModifierKey modifierKey) {
	ViewController::mouseMoveEvent(x, y, button, modifierKey);
}

void Sx::Interface::PlotController::mouseWheelEvent(int delta) {
	ViewController::mouseWheelEvent(delta);
}
